using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Web.UI;
using System.Web.UI.WebControls.WebParts;
using Microsoft.SharePoint;
using Microsoft.SharePoint.WebControls;
using System.Web.UI.WebControls;
using System.Data;
using System.ComponentModel;
using System.IO;
using Microsoft.SharePoint.WebPartPages;
using System.Xml;
using System.Xml.Linq;
using System.Linq;

namespace Tasklist
{
    [Guid("bcd75d67-4bb7-432a-8a55-efcd5f9e447a")]
    public class TaskListWebPart : Microsoft.SharePoint.WebPartPages.WebPart
    {
        private bool _error = false;

        [System.Xml.Serialization.XmlElement("tasklist")]
        [Personalizable(PersonalizationScope.Shared), WebBrowsable(true), WebDisplayName("tasklist"), WebDescription("The name of the tasklist to open")]
        [Category("Settings")]
        [WebPartStorage(Storage.Shared), Browsable(false), DefaultValue(true)]
        public string _tasklist
        {
            get;
            set;
        }

        [System.Xml.Serialization.XmlElement("Columns")]
        [Personalizable(PersonalizationScope.Shared), WebBrowsable(true), WebDisplayName("Columns"), WebDescription("The columns the webpart should lookup from the document")]
        [Category("Settings")]
        [WebPartStorage(Storage.Shared), Browsable(false), DefaultValue(true)]
        public string _columns
        {
            get;
            set;
        }

        [System.Xml.Serialization.XmlElement("ShowStatus")]
        [Personalizable(PersonalizationScope.Shared), WebBrowsable(true), WebDisplayName("Show status"), WebDescription("Adds a column with the status of the tasks")]
        [Category("Settings")]
        [WebPartStorage(Storage.Shared), Browsable(false), DefaultValue(true)]
        public bool _showstatus
        {
            get;
            set;
        }

        public TaskListWebPart()
        {
            this.ExportMode = WebPartExportMode.All;
        }

        /// <summary>
        /// Create all your controls here for rendering.
        /// Try to avoid using the RenderWebPart() method.
        /// </summary>
        protected override void CreateChildControls()
        {
            if (!_error)
            {
                try
                {

                    base.CreateChildControls();

                    //what is the current user
                    SPUser currentuser = SPContext.Current.Web.CurrentUser;
                    //reference the task list from the settings
                    SPList tasklist;
                    if (!(_tasklist == null))
                        tasklist = SPContext.Current.Web.Lists[_tasklist];
                    else { throw new SPException("Please set the name of the tasklist in the webpart properties"); }
                    //Of which groups the current user is member
                    List<int> groups = new List<int>();
                    foreach (SPGroup group in SPContext.Current.Web.Groups)
                    {
                        if (group.ContainsCurrentUser == true)
                            groups.Add(group.ID);
                    }
                    //create query to get the tasks
                    SPQuery query = new SPQuery();
                    string queryst;
                    queryst = "<Where><And>";

                    foreach (int groupid in groups)
                        queryst += "<Or>";

                    queryst +=   
                        "<Eq><FieldRef Name='AssignedTo' LookupId='TRUE'/><Value Type='User'>" + currentuser.ID.ToString() + "</Value></Eq>";

                    //add all the groups to the query
                    foreach (int groupid in groups)
                    {
                        queryst +=
                            "<Eq><FieldRef Name='TaskGroup' LookupId='TRUE'/><Value Type='User'>" + groupid.ToString() + "</Value></Eq></Or>";
                    }
                    
                   queryst +=
                       "<Neq><FieldRef Name='PercentComplete'/><Value Type='Number'>1</Value></Neq></And></Where><OrderBy><FieldRef Name='AssignedTo' /></OrderBy>";

                   query.Query = queryst;

                    //datasource
                    DataTable table = tasklist.GetItems(query).GetDataTable();
                    if (table == null)
                        throw new SPException("U heeft geen taken");

                    table.Columns.Add("Assigned to");
                    table.Columns.Add("Icon");
                    table.Columns.Add("ClaimedBy");

                    foreach (DataRow row in table.Rows)
                    {
                        string a = row["TaskGroup"].ToString();
                        string b = row["AssignedTo"].ToString();
                        if (!(string.IsNullOrEmpty(row["TaskGroup"].ToString())) && !(string.IsNullOrEmpty(row["AssignedTo"].ToString())))
                            if (!(row["AssignedTo"].ToString() == row["TaskGroup"].ToString()))
                                row["ClaimedBy"] = row["AssignedTo"];

                        if (string.IsNullOrEmpty(row["TaskGroup"].ToString()))
                        {
                            row["Assigned to"] = currentuser.Name.ToString();
                            row["Icon"] = "/_layouts/images/PERUSR.GIF";
                        }
                        else
                        {
                            if ((row["AssignedTo"].ToString() == (string)currentuser.Name))
                                row["Assigned to"] = currentuser.Name;
                            else
                                row["Assigned to"] = row["TaskGroup"].ToString();

                            row["Icon"] = "/_layouts/images/MTGICON.GIF";
                            row["AssignedTo"] = null;
                        }
                    }
                                        
                    string editurl = tasklist.ParentWeb.ContentTypes[table.Rows[0]["ContentType"].ToString()].EditFormUrl;
                    
                    SPListItem test = tasklist.Items[0];
                    
                    //Fetch all the document properties that are requested
                    XDocument columnsDocument = XDocument.Load(new StringReader(_columns));
                    var columns = from column in columnsDocument.Root.Element("Columns").Elements("Column")
                                  select column.Attribute("Name").Value;
                    foreach (var columnName in columns)
                        table.Columns.Add(columnName.ToString());
                    foreach (var columnName in columns)
                        foreach (DataRow row in table.Rows)
                        {
                            SPFile doc = GetSPFile(row["WorkflowLink"].ToString().Substring(0, row["WorkflowLink"].ToString().IndexOf(',')));
                            try
                            {
                                    row[columnName.ToString()] = doc.Item[columnName.ToString()].ToString().Replace("string;#","");
                            }
                            catch { }
                        }
                   
                    //spgridview control to show tasks
                    SPGridView grid = new SPGridView();
                    grid.AutoGenerateColumns = false;
                    grid.DataSource = table;
                    //grouping
                    grid.AllowGrouping = true;
                    grid.GroupFieldDisplayName = "Assigned to";
                    grid.GroupField = "Assigned to";

                    //columns
                    ImageField Icon = new ImageField();
                    Icon.DataImageUrlField = "Icon";
                    grid.Columns.Add(Icon);

                    SPMenuField Title = new SPMenuField();
                    Title.HeaderText = "Title";
                    Title.TextFields = "Title";
                    Title.NavigateUrlFields = "ID";
                    Title.NavigateUrlFormat = string.Format(editurl + "?List={0}&id={1}&source={2}", tasklist.ID, "{0}"  , this.Context.Request.Url.ToString());
                    Title.TokenNameAndValueFields = "VIEW=ID";
                    MenuTemplate menu = new MenuTemplate();
                    menu.ID = "Menu";
                    Controls.Add(menu);

                    MenuItemTemplate ClaimTask = new MenuItemTemplate("Eigenschappen / claimen", "/_layouts/images/GTACLAIM.GIF");
                    ClaimTask.ClientOnClickNavigateUrl = string.Format("{0}/{1}/DispForm.aspx?ID=%VIEW%&source={2}", tasklist.ParentWeb.Url, tasklist.RootFolder, this.Context.Request.Url.ToString());
                    menu.Controls.Add(ClaimTask);
                    
                    Title.MenuTemplateId = "Menu";
                    grid.Columns.Add(Title);

                    BoundField Claimedby = new BoundField();
                    Claimedby.HeaderText = "Claimed by";
                    Claimedby.DataField = "ClaimedBy";
                    
                    grid.Columns.Add(Claimedby);

                    if (_showstatus)
                    {
                        BoundField Status = new BoundField();
                        Status.HeaderText = "Status";
                        Status.DataField = "Status";
                        grid.Columns.Add(Status);
                    }

                    foreach (XElement column in columnsDocument.Root.Element("Columns").Elements("Column"))
                    {
                        BoundField extafield = new BoundField();
                        try
                        { extafield.HeaderText = column.Attribute("DisplayName").Value.ToString(); }
                        catch
                        { extafield.HeaderText = column.Attribute("Name").Value.ToString(); }

                        extafield.DataField = column.Attribute("Name").Value.ToString();
                        grid.Columns.Add(extafield);
                    }

                    grid.DataBind();

                    //add grid to controls
                    Controls.Add(grid);
                }
                catch (Exception ex)
                {
                    HandleException(ex);
                }
            }
        }

        protected SPFile GetSPFile(string url)
        {
            using (SPSite site = new SPSite(url))
            {
                using (SPWeb web = site.OpenWeb())
                {
                    SPFile file = web.GetFile(url);
                    return file;
                }
            }
        }

        /// <summary>
        /// Ensures that the CreateChildControls() is called before events.
        /// Use CreateChildControls() to create your controls.
        /// </summary>
        /// <param name="e"></param>
        protected override void OnLoad(EventArgs e)
        {
            if (!_error)
            {
                try
                {
                    base.OnLoad(e);
                    this.EnsureChildControls();

                    // Your code here...
                }
                catch (Exception ex)
                {
                    HandleException(ex);
                }
            }
        }

        /// <summary>
        /// Clear all child controls and add an error message for display.
        /// </summary>
        /// <param name="ex"></param>
        private void HandleException(Exception ex)
        {
            this._error = true;
            this.Controls.Clear();
            this.Controls.Add(new LiteralControl(ex.Message));
        }
    }
}
